home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
cool
/
ge_cool.lha
/
GE_COOL2.1
/
src
/
Matrix
/
Matrix.h
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-01
|
14KB
|
375 lines
//
// Copyright (C) 1991 Texas Instruments Incorporated.
// Copyright (C) 1992 General Electric Company.
//
// Permission is granted to any individual or institution to use, copy, modify,
// and distribute this software, provided that this complete copyright and
// permission notice is maintained, intact, in all copies and supporting
// documentation.
//
// Texas Instruments Incorporated, General Electric Company,
// provides this software "as is" without express or implied warranty.
//
// Created: MBN 04/21/89 -- Initial design and implementation
// Updated: MBN 06/22/89 -- Removed non-destructive methods
// Updated: LGO 08/09/89 -- Inherit from Generic
// Updated: MBN 08/20/89 -- Changed template usage to reflect new syntax
// Updated: MBN 09/11/89 -- Added conditional exception handling and base class
// Updated: LGO 10/05/89 -- Don't re-allocate data in operator= when same size
// Updated: LGO 10/19/89 -- Add extra parameter to varargs constructor
// Updated: MBN 10/19/89 -- Added optional argument to set_compare method
// Updated: LGO 12/08/89 -- Allocate column data in one chunk
// Updated: LGO 12/08/89 -- Clean-up get and put, add const everywhere.
// Updated: LGO 12/19/89 -- Remove the map and reduce methods
// Updated: MBN 02/22/90 -- Changed size arguments from int to unsigned int
// Updated: MJF 06/30/90 -- Added base class name to constructor initializer
// Updated: VDN 02/21/92 -- New lite version
// Updated: VDN 05/05/92 -- Use envelope to avoid unecessary copying
//
// The parameterized Matrix<Type> class is publicly derived from the Matrix
// class and implements two dimensional arithmetic matrices of a user specified
// type. This is accompilshed by using the parameterized type capability of
// C++. The only constraint placed on the type is that it must overload the
// following operators: +, -, *, and /. Thus, it will be possible to have a
// Matrix of type Complex. The Matrix<Type> class is static in size, that is
// once a Matrix<Type> of a particular size has been declared, there is no
// dynamic growth or resize method available.
//
// Each matrix contains a protected data section that has a Type** slot that
// points to the physical memory allocated for the two dimensional array. In
// addition, two integers specify the number of rows and columns for the
// matrix. These values are provided in the constructors. A single protected
// slot contains a pointer to a compare function to be used in equality
// operations. The default function used is the built-in == operator.
//
// Four different constructors are provided. The first constructor takes two
// integer arguments specifying the row and column size. Enough memory is
// allocated to hold row*column elements of type Type. The second constructor
// takes the same two first arguments, but also accepts an additional third
// argument that is a reference to an object of the appropriate type whose
// value is used as an initial fill value. The third constructor is similar to
// the third, except that it accpets a variable number of initialization values
// for the Matrix. If there are fewer values than elements, the rest are set
// to zero. Finally, the last constructor takes a single argument consisting of
// a reference to a Matrix and duplicates its size and element values.
//
// Methods are provided for destructive scalar and Matrix addition,
// multiplication, check for equality and inequality, fill, reduce, and access
// and set individual elements. Finally, both the input and output operators
// are overloaded to allow for fomatted input and output of matrix elements.
#ifndef MATRIXH // If no Matrix class,
#define MATRIXH // define it
#ifndef STDARGH
#if defined(DOS)
extern "C" {
#include <stdarg.h> // for variable arglists
}
#else
#include <stdarg.h> // for variable arglists
#endif
#define STDARGH
#endif
#ifndef BASE_MATRIXH // If no base class definition
#include <cool/Base_Matrix.h> // include it
#endif
template<class Type> CoolMatrix {
typedef Boolean (*Type##_CoolMatrix_Compare) (const Type&, const Type&);
class CoolMatrix<Type>E; // forward declaration for envelope
}
template<class Type>
class CoolMatrix<Type> : public CoolMatrix {
// friend class CoolVec<Type>; // not feasible with COOLcpp
public:
CoolMatrix<Type> (unsigned int r=1, unsigned int c=1); // m (r,c);
CoolMatrix<Type> (unsigned int r, unsigned int c, const Type& v0); // m(r,c,init);
CoolMatrix<Type> (unsigned int r, unsigned int c, int n,
Type v00, ...);
CoolMatrix<Type> (unsigned int r, unsigned int c, // from a block of data
const Type* data_block); // stored row-wise.
CoolMatrix<Type> (const CoolMatrix<Type>&); // m1 = m2;
~CoolMatrix<Type>(); // Destructor
inline void put (unsigned int r, unsigned int, Type&); // Assign value
inline Type& get (unsigned int r, unsigned int); // Get value
void fill (const Type&); // Set elements to value
inline Type& operator() (unsigned int r, unsigned int c=0); // Access wo checks
CoolMatrix<Type>& operator= (const Type&); // Assignment: m = 2;
CoolMatrix<Type>& operator= (const CoolMatrix<Type>&); // Assignment: m = n;
inline CoolMatrix<Type>& operator= (CoolMatrix<Type>E&);
Boolean operator== (const CoolMatrix<Type>&) const; // CoolMatrix equality test
inline Boolean operator!= (const CoolMatrix<Type>&) const; // inequality test
void set_compare (Type##_CoolMatrix_Compare = NULL); // Compare function
inline friend ostream& operator<< (ostream&, const CoolMatrix<Type>*);
friend ostream& operator<< (ostream&, const CoolMatrix<Type>&);
CoolMatrix<Type>& operator+= (const Type&); // binary operation and assignment
CoolMatrix<Type>& operator*= (const Type&); // Mutate matrix data
CoolMatrix<Type>& operator/= (const Type&);
inline CoolMatrix<Type>& operator-= (const Type&);
CoolMatrix<Type>& operator+= (const CoolMatrix<Type>&);
CoolMatrix<Type>& operator-= (const CoolMatrix<Type>&);
inline CoolMatrix<Type>& operator*= (const CoolMatrix<Type>&);
CoolMatrix<Type>E operator- () const; // negation and
CoolMatrix<Type>E operator+ (const Type&) const; // all binary operations
CoolMatrix<Type>E operator* (const Type&) const; // return by values.
CoolMatrix<Type>E operator/ (const Type&) const;
inline CoolMatrix<Type>E operator- (const Type&) const;
inline friend CoolMatrix<Type>E operator+ (const Type&, const CoolMatrix<Type>&);
inline friend CoolMatrix<Type>E operator- (const Type&, const CoolMatrix<Type>&);
inline friend CoolMatrix<Type>E operator* (const Type&, const CoolMatrix<Type>&);
// Fewer unnecessary copying with CoolEnvelope
// friend CoolMatrix<Type>E operator+ (const CoolMatrix<Type>&,
// const CoolMatrix<Type>&);
// friend CoolMatrix<Type>E operator- (const CoolMatrix<Type>&,
// const CoolMatrix<Type>&);
friend CoolMatrix<Type>E operator* (const CoolMatrix<Type>&,
const CoolMatrix<Type>&);
////--------------------------- Additions ------------------------------------
CoolMatrix<Type>E transpose () const; // transpose row/column
CoolMatrix<Type>E abs () const; // absolute of all elements
CoolMatrix<Type>E sign () const;
CoolMatrix<Type>E extract (unsigned int rows, unsigned int cols, // get submatrix
unsigned int top=0, unsigned int left=0) const;
CoolMatrix<Type>& update (const CoolMatrix<Type>&, // update submatrix
unsigned int top=0, unsigned int left=0);
friend CoolMatrix<Type>E element_product (const CoolMatrix<Type>&, // a[ij]*b[ij]
const CoolMatrix<Type>&);
friend CoolMatrix<Type>E element_quotient (const CoolMatrix<Type>&, // a[ij]/b[ij]
const CoolMatrix<Type>&);
Type determinant() const; // determinant of square matrix
////--------------------------- Vector ---------------------------------------
inline Type& x (); // using a 2d matrix
inline Type& y (); // to represent a 1d vector
inline Type& z (); // is less efficient
inline Type& t (); // in time and space
friend Type dot_product (const CoolMatrix<Type>&, // dot-product of n-dim vectors
const CoolMatrix<Type>&);
friend Type cross_2d (const CoolMatrix<Type>&, // cross-product of 2d-vectors
const CoolMatrix<Type>&);
friend CoolMatrix<Type>E cross_3d (const CoolMatrix<Type>&, // cross-product
const CoolMatrix<Type>&); // of 3d-vectors
inline const Type* data_block (); // block of data, row-major order.
protected:
Type** data; // Pointer to the CoolMatrix
static Type##_CoolMatrix_Compare compare_s; // Pointer operator== function
friend Boolean Type##_CoolMatrix_is_data_equal (const Type&, const Type&);
};
// Avoid deep copy on return by value, add and subtract in place.
template<class Type> CoolMatrix {
typedef int ________int; // Coolcpp hack, get rid off it soon
#define ENVELOPE_PLUS // the operators +=, -=,
#define ENVELOPE_MINUS // can be done in place
#define CoolLetter CoolMatrix<Type>
#define CoolEnvelope CoolMatrix_##Type##E // for Coolcpp parsing
#include <cool/Envelope.h> // Include envelope macros
#undef CoolLetter
#undef CoolEnvelope
#undef ENVELOPE_PLUS
#undef ENVELOPE_MINUS
}
// get -- Get the element at specified index and return value
// Input: this*, row, column
// Output: Element value
template<class Type>
inline Type& CoolMatrix<Type>::get (unsigned int row, unsigned int column) {
#if ERROR_CHECKING
if (row >= this->num_rows) // If invalid size specified
this->row_index_error ("get", #Type, row); // Raise exception
if (column >= this->num_cols) // If invalid size specified
this->col_index_error ("get", #Type, column); // Raise exception
#endif
return this->data[row][column];
}
// put -- Put the element value at specified index
// Input: *this, row, column, value
// Output: Element value
template<class Type>
inline void CoolMatrix<Type>::put (unsigned int row, unsigned int column, Type& value) {
#if ERROR_CHECKING
if (row >= this->num_rows) // If invalid size specified
this->row_index_error ("put", #Type, row); // Raise exception
if (column >= this->num_cols) // If invalid size specified
this->col_index_error ("put", #Type, column); // Raise exception
#endif
this->data[row][column] = value; // Assign data value
}
// operator() -- Overload () to get the element at specified index
// and return by reference
// Input: this*, row, column
// Output: Element value
template<class Type>
inline Type& CoolMatrix<Type>::operator() (unsigned int row, unsigned int column) {
return this->data[row][column]; // fast access without checks.
}
// operator= -- Assignment from an envelope back to real matrix
// Input: envelope reference
// Output: matrix reference with contents in envelope being swapped over
template<class Type>
inline CoolMatrix<Type>& CoolMatrix<Type>::operator= (CoolMatrix<Type>E& env){
env.shallow_swap((CoolMatrix<Type>E*)this, &env); // same physical layout
return *this;
}
// operator<< -- Overload the output operator to print a CoolMatrix
// Input: ostream reference, CoolMatrix pointer
// Output: ostream reference
template<class Type> CoolMatrix {
inline ostream& operator<< (ostream& os, const CoolMatrix<Type>* m) {
if (m) os << *m;
return os;
}}
// operator!= -- Perform not equal comparison test
// Input: this*, matrix reference
// Output: TRUE/FALSE
template<class Type>
inline Boolean CoolMatrix<Type>::operator!= (const CoolMatrix<Type>& m) const {
return (!operator== (m));
}
// operator-= -- Destructive matrix subtraction of a scalar.
// Input: this*, scalar value
// Output: New matrix reference
template<class Type>
inline CoolMatrix<Type>& CoolMatrix<Type>::operator-= (const Type& value) {
return *this += (- value);
}
template<class Type> CoolMatrix {
inline CoolMatrix<Type>E operator+ (const Type& value,
const CoolMatrix<Type>& m) {
return m + value;
}}
// operator- -- Non-destructive matrix substraction of a scalar.
// Input: this*, scalar value
// Output: New matrix
template<class Type>
inline CoolMatrix<Type>E CoolMatrix<Type>::operator-(const Type& value) const {
return (*this) + (- value);
}
template<class Type> CoolMatrix {
inline CoolMatrix<Type>E operator- (const Type& value,
const CoolMatrix<Type>& m) {
return (- m) + value;
}}
template<class Type> CoolMatrix {
inline CoolMatrix<Type>E operator* (const Type& value,
const CoolMatrix<Type>& m) {
return m * value;
}}
template<class Type>
inline CoolMatrix<Type>& CoolMatrix<Type>::operator*= (const CoolMatrix<Type>&m) {
*this = (*this) * m; // multiply, then shallow swap
return *this;
}
////-------------------------- Vector ----------------------------------
//// use a column matrix to represent 1d vector
template<class Type>
inline Type& CoolMatrix<Type>::x(){
return data[0][0];
}
template<class Type>
inline Type& CoolMatrix<Type>::y() {
return data[1][0];
}
template<class Type>
inline Type& CoolMatrix<Type>::z() {
return data[2][0];
}
template<class Type>
inline Type& CoolMatrix<Type>::t() {
return data[3][0];
}
// template<class Type> // use a row matrix to
// inline Type& CoolMatrix<Type>::x() { // represent 1d vector
// return data[0][0];
// }
//
// template<class Type>
// inline Type& CoolMatrix<Type>::y() {
// return data[0][1];
// }
//
// template<class Type>
// inline Type& CoolMatrix<Type>::z() {
// return data[0][2];
// }
//
// template<class Type>
// inline Type& CoolMatrix<Type>::t() {
// return data[0][3];
// }
// data_block -- Provide access to the contiguous block storing
// the elements in the matrix row-wise.
// Use this only to cast matrix contents,
// to C array like: Type [rows][columns].
template<class Type>
inline const Type* CoolMatrix<Type>::data_block () {
return data[0]; // start of array of data
}
#endif // End of MATRIXH